package com.three.mahjong.base.rule;

import com.three.mahjong.base.model.Card;
import com.three.mahjong.base.model.CardSmallType;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by YW0981 on 2017/7/17.
 */
public class MJBaseHuPaiRule {

    /**
     * 是否是小三元
     * @param cards
     * @param paiXingSet
     * @return
     */
    public static boolean isXiaoSanYuan(List<Card> cards, Set<CardSmallType> paiXingSet) {
        int[] count = new int[100];
        // 统计牌的计数
        for(Card card : cards) {
            ++count[card.getCardSmallType().getCode()];
        }
        int duiZiCount = 0;
        int keZiAndGangZiCount = 0;
        for(CardSmallType smallType : paiXingSet) {
            // 将刻子、杠子置0
            if(count[smallType.getCode()] == 3 || count[smallType.getCode()] == 4) {
                count[smallType.getCode()] = 0;
                ++keZiAndGangZiCount;
            }
            // 不能出现一个牌
            if(count[smallType.getCode()] == 1)
                return false;
            if(count[smallType.getCode()] == 2) {
                count[smallType.getCode()] = 0;
                ++duiZiCount;
            }
        }
        // 对子只能有一个
        if(keZiAndGangZiCount != 2 || duiZiCount != 1)
            return false;
        // 剩下的排必须要么是杠子、要么是顺子、要么是刻子
        for(int i = 0; i < 100; ++i) {
            if(count[i] == 3 || count[i] == 4)
                count[i] = 0;
            else if(count[i] == 1) {
                if(i + 1 >= 100 || i + 2 >= 100)
                    return false;
                if(count[i + 1] != 1 || count[i + 2] != 1)
                    return false;
                count[i] = count[i + 1] = count[i + 2] = 0;
            }
        }
        return true;
    }

    /**
     * 是否是小四喜
     * @param cards
     * @param paiXingSet
     * @return
     */
    public static boolean isXiaoSiXi(List<Card> cards, Set<CardSmallType> paiXingSet) {
        int[] count = new int[100];
        // 统计牌的计数
        for(Card card : cards) {
            ++count[card.getCardSmallType().getCode()];
        }
        int duiZiCount = 0;
        int keZiAndGangZiCount = 0;
        for(CardSmallType smallType : paiXingSet) {
            // 将刻子、杠子置0
            if(count[smallType.getCode()] == 3 || count[smallType.getCode()] == 4) {
                count[smallType.getCode()] = 0;
                ++keZiAndGangZiCount;
            }
            // 不能出现一个牌
            if(count[smallType.getCode()] == 1)
                return false;
            if(count[smallType.getCode()] == 2) {
                count[smallType.getCode()] = 0;
                ++duiZiCount;
            }
        }
        // 对子只能有一个
        if(keZiAndGangZiCount != 3 || duiZiCount != 1)
            return false;
        // 还剩最后3个必须组成刻子或者顺子
        for(int i = 0; i < 100; ++i) {
            if(count[i] == 3)
                count[i] = 0;
            else if(count[i] == 1) {
                if(i + 1 >= 100 || i + 2 >= 100)
                    return false;
                if(count[i + 1] != 1 || count[i + 2] != 1)
                    return false;
                count[i] = count[i + 1] = count[i + 2] = 0;
            }
        }
        return true;
    }

    /**
     * 是否是字一色
     * @param cards
     * @param paiXingSet
     * @return
     */
    public static boolean isZiYiSe(List<Card> cards, Set<CardSmallType> paiXingSet) {
        int[] count = new int[100];
        // 统计牌的计数
        for(Card card : cards) {
            ++count[card.getCardSmallType().getCode()];
        }
        int duiZiCount = 0;
        for(CardSmallType smallType : paiXingSet) {
            // 将刻子、杠子置0
            if(count[smallType.getCode()] == 3 || count[smallType.getCode()] == 4)
                count[smallType.getCode()] = 0;
            // 不能出现一个牌
            if(count[smallType.getCode()] == 1)
                return false;
            // 对子不能出现超过1次
            if(count[smallType.getCode()] == 2) {
                count[smallType.getCode()] = 0;
                ++duiZiCount;
            }
        }
        // 也有可能是七对子
        if(duiZiCount != 1 || duiZiCount != 7)
            return false;
        // 不能出现牌型以外的牌
        for(int i = 0; i < 100; ++i) {
            if(count[i] != 0)
                return false;
        }
        return true;
    }

    /**
     * 是否是清幺九
     * @param cards
     * @param paiXingSet
     * @return
     */
    public static boolean isQingYaoJiu(List<Card> cards, Set<CardSmallType> paiXingSet) {
        int[] count = new int[100];
        // 统计牌的计数
        for(Card card : cards) {
            ++count[card.getCardSmallType().getCode()];
        }
        int duiZiCount = 0;
        for(CardSmallType smallType : paiXingSet) {
            // 将刻子、杠子置0
            if(count[smallType.getCode()] == 3 || count[smallType.getCode()] == 4)
                count[smallType.getCode()] = 0;
            // 不能出现一个牌
            if(count[smallType.getCode()] == 1)
                return false;
            // 对子不能出现超过1次
            if(count[smallType.getCode()] == 2) {
                count[smallType.getCode()] = 0;
                ++duiZiCount;
                if(duiZiCount > 1)
                    return false;
            }
        }
        // 对子必须出现一次
        if(duiZiCount != 1)
            return false;
        // 不能出现牌型以外的牌
        for(int i = 0; i < 100; ++i) {
            if(count[i] != 0)
                return false;
        }
        return true;
    }

    /**
     * 是否是大四喜
     * @param cards
     * @param paiXingSet
     * @return
     */
    public static boolean isDaSiXi(List<Card> cards, Set<CardSmallType> paiXingSet) {
        int[] count = new int[100];
        for(Card card : cards) {
            ++count[card.getCardSmallType().getCode()];
        }
        for(CardSmallType smallType : paiXingSet) {
            if(count[smallType.getCode()] != 3 || count[smallType.getCode()] != 4)
                return false;
            count[smallType.getCode()] = 0;
        }
        for(int i = 0; i < 99; ++i) {
            if(count[i] != 0 && count[i] != 2)
                return false;
        }
        return true;
    }

    /**
     * 是否是十三幺
     * @param cards
     * @param paiXingSet
     * @return
     */
    public static boolean isShiSanYao(List<Card> cards, Set<CardSmallType> paiXingSet) {
        Set<CardSmallType> tmpSmallTypes = new HashSet<>();
        for(Card card : cards) {
            tmpSmallTypes.add(card.getCardSmallType());
        }
        return tmpSmallTypes.containsAll(paiXingSet);
    }

    /**
     * 是否是大三元
     * @param cards
     * @param paiXingSet
     * @return
     */
    public static boolean isDaSanYuan(List<Card> cards, Set<CardSmallType> paiXingSet) {
        int[] count = new int[100];
        for(Card card : cards) {
            ++count[card.getCardSmallType().getCode()];
        }
        for(CardSmallType smallType : paiXingSet) {
            if(count[smallType.getCode()] != 3 || count[smallType.getCode()] != 4)
                return false;
            count[smallType.getCode()] = 0;
        }
        for(int i = 0; i < 100; ++i) {
            if(count[i] == 4 || count[i] == 2 || count[i] == 3)
                count[i] = 0;
            else if(count[i] == 1) {
                if(i + 1 >= 100 || i + 2 >= 100)
                    return false;
                if(count[i + 1] != 1 || count[i + 2] != 1)
                    return false;
                count[i] = count[i + 1] = count[i + 2] = 0;
            }
        }
        return true;
    }


}
